package com.xujie.sportsmeeting.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xujie.sportsmeeting.dto.RoleQueryDTO;
import com.xujie.sportsmeeting.entity.SysRole;
import com.xujie.sportsmeeting.entity.SysPermission;
import com.xujie.sportsmeeting.entity.SysRolePermission;
import com.xujie.sportsmeeting.mapper.SysRoleMapper;
import com.xujie.sportsmeeting.mapper.SysPermissionMapper;
import com.xujie.sportsmeeting.mapper.SysRolePermissionMapper;
import com.xujie.sportsmeeting.service.SysRoleService;
import com.xujie.sportsmeeting.vo.PermissionVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统角色服务实现类
 */
@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    private final SysPermissionMapper sysPermissionMapper;
    private final SysRolePermissionMapper sysRolePermissionMapper;

    @Override
    public IPage<SysRole> getRolePage(IPage<SysRole> page, RoleQueryDTO queryDTO) {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(queryDTO.getRoleName())) {
            wrapper.like(SysRole::getRoleName, queryDTO.getRoleName());
        }
        
        if (StringUtils.hasText(queryDTO.getRoleCode())) {
            wrapper.like(SysRole::getRoleCode, queryDTO.getRoleCode());
        }
        
        if (queryDTO.getStatus() != null) {
            wrapper.eq(SysRole::getStatus, queryDTO.getStatus());
        }
        
        wrapper.orderByDesc(SysRole::getCreateTime);
        
        return this.page(page, wrapper);
    }

    @Override
    @Transactional
    public boolean createRole(SysRole role) {
        // 检查角色编码是否已存在
        SysRole existingRole = findByRoleCode(role.getRoleCode());
        if (existingRole != null) {
            throw new RuntimeException("角色编码已存在");
        }
        
        return this.save(role);
    }

    @Override
    @Transactional
    public boolean updateRole(SysRole role) {
        // 检查角色编码是否已存在（排除当前角色）
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getRoleCode, role.getRoleCode())
               .ne(SysRole::getId, role.getId());
        SysRole existingRole = this.getOne(wrapper);
        if (existingRole != null) {
            throw new RuntimeException("角色编码已存在");
        }
        
        return this.updateById(role);
    }

    @Override
    public boolean updateRoleStatus(Long roleId, Integer status) {
        SysRole role = new SysRole();
        role.setId(roleId);
        role.setStatus(status);
        return this.updateById(role);
    }

    @Override
    public List<String> findPermissionsByRoleId(Long roleId) {
        // 查询角色权限关联
        LambdaQueryWrapper<SysRolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRolePermission::getRoleId, roleId);
        List<SysRolePermission> rolePermissions = sysRolePermissionMapper.selectList(wrapper);
        
        if (rolePermissions.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取权限ID列表
        List<Long> permissionIds = rolePermissions.stream()
                .map(SysRolePermission::getPermissionId)
                .collect(Collectors.toList());
        
        // 查询权限信息
        List<SysPermission> permissions = sysPermissionMapper.selectBatchIds(permissionIds);
        
        return permissions.stream()
                .map(SysPermission::getPermissionCode)
                .collect(Collectors.toList());
    }

    @Override
    public List<Long> findPermissionIdsByRoleId(Long roleId) {
        LambdaQueryWrapper<SysRolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRolePermission::getRoleId, roleId);
        List<SysRolePermission> rolePermissions = sysRolePermissionMapper.selectList(wrapper);
        
        return rolePermissions.stream()
                .map(SysRolePermission::getPermissionId)
                .collect(Collectors.toList());
    }

    @Override
    public List<PermissionVO> getAllPermissions() {
        // 查询所有权限
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysPermission::getStatus, 1)
               .orderByAsc(SysPermission::getSortOrder);
        List<SysPermission> permissions = sysPermissionMapper.selectList(wrapper);
        
        // 转换为VO
        List<PermissionVO> permissionVOs = permissions.stream().map(permission -> {
            PermissionVO vo = new PermissionVO();
            BeanUtils.copyProperties(permission, vo);
            return vo;
        }).collect(Collectors.toList());
        
        // 构建树形结构
        return buildPermissionTree(permissionVOs, 0L);
    }

    @Override
    @Transactional
    public boolean assignRolePermissions(Long roleId, List<Long> permissionIds) {
        // 删除原有权限关联
        LambdaQueryWrapper<SysRolePermission> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(SysRolePermission::getRoleId, roleId);
        sysRolePermissionMapper.delete(deleteWrapper);
        
        // 添加新的权限关联
        if (permissionIds != null && !permissionIds.isEmpty()) {
            List<SysRolePermission> rolePermissions = permissionIds.stream().map(permissionId -> {
                SysRolePermission rolePermission = new SysRolePermission();
                rolePermission.setRoleId(roleId);
                rolePermission.setPermissionId(permissionId);
                return rolePermission;
            }).collect(Collectors.toList());
            
            // 批量插入
            for (SysRolePermission rolePermission : rolePermissions) {
                sysRolePermissionMapper.insert(rolePermission);
            }
        }
        
        return true;
    }

    @Override
    public SysRole findByRoleCode(String roleCode) {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getRoleCode, roleCode);
        return this.getOne(wrapper);
    }

    /**
     * 构建权限树形结构
     */
    private List<PermissionVO> buildPermissionTree(List<PermissionVO> permissions, Long parentId) {
        List<PermissionVO> tree = new ArrayList<>();
        
        for (PermissionVO permission : permissions) {
            if (permission.getParentId().equals(parentId)) {
                List<PermissionVO> children = buildPermissionTree(permissions, permission.getId());
                permission.setChildren(children);
                tree.add(permission);
            }
        }
        
        return tree;
    }
}
